var Koa = require('koa'),
    router = require('koa-router')();
var url = require('url');
const static_ = require('koa-static')
const fs = require("fs");
const multer  = require('@koa/multer')
const path = require('path')
const UserModel = require('./dbs').User
const FriendsModel = require('./dbs').Friends
const { aesEncrypt, aesDecrypt } = require('./utils');

const upload = multer({ dest: './public/upload' });
const EventEmitter = require('events');

const IO = require( 'koa-socket' )
const io = new IO();
var app = new Koa();
var port = 3080;
io.attach( app );
var INIT_NOTICE = true;
const MsgEvent = new EventEmitter();

app.use(async (ctx, next) => {
  
  const start = Date.now();
  await next();
  const ms = Date.now() - start;
  ctx.set('X-Response-Time', `${ms}ms`);
  // Access-Control-Allow-Credentials 设置为true会和 Access-Control-Allow-Origin":"*" 冲突的
  ctx.set("Access-Control-Allow-Credentials", false);
  // 这里获取 origin 请求头 而不是用 *
  ctx.set("Access-Control-Allow-Origin", "*");
  ctx.set("Access-Control-Allow-Headers", "X-Requested-With,Content-Type,Authorization,token");
  ctx.set("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS,HEADER");
  const { method, url } = ctx;
  const urlDownloadReg = /\/upload\//;
  if (urlDownloadReg.test(url)&&method == 'GET') {
    ctx.set("Content-Disposition", `attachment; filename="${url.replace(urlDownloadReg, '')}"`);
  }
  // ctx.set("Content-Type", "application/json;charset=utf-8");
});

// router.get('/upload/:filename', async (ctx) => {
//   console.log(ctx)
//   ctx.set("Content-Disposition", `attachment; filename="filename.jpg"`);
// })

app.use(static_(
  path.join(__dirname, './public/')
))

router.get('/',async (ctx)=>{
    ctx.body = 'index';
})

router.post('/upload-single', upload.single('image'),async (ctx, next) => {
  let file = Date.parse(new Date())+Math.random().toString(36).substr(2,5).toUpperCase()+'.'+ctx.file.originalname.split('.').reverse()[0]
  fs.renameSync(ctx.file.path,ctx.file.destination+'/'+file);
  ctx.body = {
      code: 200,
      msg: '上传成功！',
      file: file
  }
})


router.get('/notice',async (ctx)=> {
    const { msg = '' } = ctx.request.query
    MsgEvent.emit('notice', msg)
    ctx.body = 'ok';
})

app.use(router.routes());   /*启动路由*/
app.use(router.allowedMethods());
var numUsers = 0;
app._io.on( 'connection', socket => {
    
    var addedUser = false;

    var groupid = url.parse(socket.request.url,true).query.groupid || 1516;   // 获取分组号
    console.log('建立连接了',groupid);
    // socket.join(groupid);  // 加入分组
    if (INIT_NOTICE) {
      INIT_NOTICE = false
      MsgEvent.on('notice', function(msg) {
          socket.broadcast.emit('notice', {
              msg
          })
      })
    }
    socket.on('new message', (data) => {
        // we tell the client to execute 'new message'
        socket.broadcast.emit('new message', {
          username: socket.username,
          message: data
        });
      });
    socket.on('add user', (loginInfo) => {
        if (addedUser) return;
        const { username, userid } = loginInfo
        socket.username = username;
        socket.userid = userid;
        ++numUsers;
        addedUser = true;
        socket.emit('login', {
          numUsers: numUsers,
        });
        socket.broadcast.emit('user joined', {
          username: socket.username,
          userid: socket.userid,
          numUsers: numUsers
        });
    });

    socket.on('user joined', (data) => {
      socket.broadcast.emit('user joined', {
        username: data.username,
        userid: data.userid,
        numUsers: numUsers
      });
    })

    socket.on('get users', (e) => {
      const { userid } = e
      socket.broadcast.emit('is online', userid);
    })

    socket.on('i am online', r => {
      const { fr, to } = r;
      socket.broadcast.emit(`online ${to}`, {
        fr
      })
    })

    socket.on('exchange', data => { 
      const { msg, userid, type = '', fr } = data;
      console.log(data);
      if (userid == fr) {
        socket.emit(userid, { msg, fr, type })
      } else {
        socket.broadcast.emit(userid, { msg, fr, type })
      }
    });

    socket.on('typing', () => {
        socket.broadcast.emit('typing', {
          username: socket.username
        });
      });
    
      // when the client emits 'stop typing', we broadcast it to others
      socket.on('stop typing', () => {
        socket.broadcast.emit('stop typing', {
          username: socket.username
        });
      });
      socket.on('disconnect', () => {
        if (addedUser) {
          --numUsers;
          // echo globally that this client has left
          socket.broadcast.emit('user left', {
            username: socket.username,
            userid: socket.userid,
            numUsers: numUsers
          });
        }
      });
    // 监听客户端连接
      socket.on('question',function(data) {
          // socket.emit('serverMsg','我是服务器，我给客户端发送信息');  // 单播：单个socket互不影响，谁给我发的信息我回返回给谁

          // app._io.emit('serverMsg','我是服务器，我给客户端发送信息');  // 广播: 所有建立连接的客户端

          // app._io.emit('serverMsg','我是服务器，我给客户端发送信息'); // 发送给指定分组内的用户 通知自己

          socket.broadcast.emit('question','我是服务器，我给客户端发送信息'); // 通知指定分组用户 不通知自己
      })
})

app.listen(port);
console.log('oJBk','serve at localhost:'+port)